Isolamento strumentale

di Edoardo Oldani S4675431

collaboratore: Gabriele Lanteri S4638890

Questo notebook è stato realizzato con l'idea di analizzare una canzone e riuscire a scomporla in più parti. La scomposizione eseguita divide la traccia iniziale in parte armonica e percussiva. Dopodiché isoleremo la parte strumentale rimuovendo la parte vocale e riapplicheremo lo stesso procedimento per avere come risultato solo parte musicale divisa in parte armonica e percussiva.

Prima parte, inizializzazione progetto:

Il progetto inizia importando librerie e caricando all'interno del notebook la traccia audio.

Iniziamo importando le librerie standard python e per il progetto utilizzeremo Librosa

Selezioniamo la canzone ed impostiamo la durata che vogliamo salvare e la carichiamo

Il metodo load carica un file audio come una serie temporale a floating point (y) che verrà ricampionato automaticamente alla frequenza indicata (sr, default=22050)

Riproduco e plotto il grafico

Ne eseguo la trasformata di Fourier discreta e dopodiché convertiamo lo spettrogramma in uno deciBell-scaled e lo mostriamo

La "stft" è la short time Fourier transform: consiste nella trasformata di Fourier ma divide un segnale a lunga durata e lo divide in segmenti della stessa lunghezza, dopodiché ne esegue per ognuno la trasformata di Fourier.

Plotto lo spettrogramma

Siccome il range di pressione sonora percepibile è molto più ampio rispetto alla percezione umana approssimiamo la scala di valori utilizzando "amplitude_to_db" che converte il segnale in una scala logaritmica. Il risultato quindi è un plot in cui riusciamo a vedere corrispondenze con quello che sentiamo.

Lo spettrogramma rappresenta un segnale che mostra la relazione tra 3 variabili che caratterizzano qualsiasi suono:

Attraverso l’uso di uno spettrogramma è possibile rendersi conto di come è costituito un suono.

Terza parte, creazione maschere:

In questa parte andiamo a ricavare la parte armonica e percussiva calcolando delle maschere e applicandole al segnale.

Ricaviamo le due maschere

Per trovare le due maschere andremo ad utilizzare il metodo che utilizza la funzione chiamata in precedenza per trovare le due parti in modo rapido: librosa.decompose.hpss. Siccome il metodo in precedenza chiamava in pipeline tre metodi esterni noi andremo a passare alla decompose il risultato della stft. Il parametro "margin" permette di isolare al meglio le singole parti, se il valore è una tupla allora andiamo ad esaltare con valori diversi le due parti (harm,perc)

Mostriamo le due maschere

Stabiliamo i giusti valori per isolare meglio le componenti

Rendiamo positivi tutti i valori del segnale dopo la trasformata di Fourier e troviamo la potenza giusta, che quindi isoli bene le due parti limitando il più possibili errori o "buchi", ricavando il segnale intero.

Infine calcoliamo la fase che non è una proprietà di un solo segnale ma implica invece la relazione tra due o più segnali che condividono la stessa frequenza. Se i picchi di due segnali con la stessa frequenza sono esattamente allineati allo stesso tempo si dice che sono in fase.

Calcoliamo la parte armonica e percussiva

Adesso andiamo ad applicare la maschera al segnale iniziale e moltiplichiamo anche per la phase. Dopo questi calcoli ci basta effettuare la trasformata di Fourier inversa per ottenere i due segnali divisi.

Mostriamo il segnale e ascoltiamo le tracce

Quarta parte, spettrogrammi a confronto:

In questa parte andremo a mostrare ed analizzare gli spettrogrammi della traccia e delle parti trovate in precedenza.

Decompongo lo spettrogramma

Questa volta non andiamo a creare delle maschere da applicare poi al segnale ma andremo a ritornare gli spettrogrammi relativi a parte armonica e percussiva. Assegnando al "margin" un valore maggiore di 1.0 andremo anche a ricavare il residuo, quindi i valori che non appartengono a nessuna delle due parti, utilizziamo il valore impostato al momento della creazione delle maschere.

Visualizzazione degli spettrogrammi

Il primo plot è lo spettrogramma relativo alla canzone iniziale senza modifiche, gli altri due sono gli spettrogrammi della canzone filtrata (senza rumore) con la maschera relativa applicata

Spettrogramma del residuo

Come si può notare i valori del residuo sono alti, questo perché essendo una canzone complessa, con molti strumenti, è difficile isolare solo la parte armonica e percussiva

Quinta parte, separazione della parte strumentale:

Adesso separiamo la parte strumentale da quella vocale, per farlo andremo prima a rimuovere il rumore e successivamente a creare ed applicare una maschera

Filtriamo il segnale rimuovendo il rumore

Utilizziamo la nn_filter per pulire il segnale, la metrica è del coseno quindi applichiamo la similarità del coseno e separiamo i frame simili di almeno 2 secondi in modo tale da non essere ingannati dalla continuità locale.

In seguito andiamo a prendere i valori minimi di entrambi i segnali

Creiamo la maschera per la parte strumentale

Per creare la maschera questa volta utilizziamo il metodo softmask, utilizzato internamente anche da decompose.hpss. Come parametro per la maschera abbiamo bisogno di una potenza e di un margine, utilizzato per accentuare valori bassi e quindi isolare solo la parte strumentale

Ricaviamo il risultato della separazione

Applichiamo la maschera al segnale filtrato e ne effettuiamo la trasformata di Fourier inversa per ottenere la traccia audio filtrata della parte vocale

Sesta parte, divisione del background :

Nell'ultima parte del notebook, andremo a dividere in componente armonica e percussiva la traccia senza la parte vocale.

Scomponiamo la traccia in parte armonica e percussiva

Per non ripetere le stesse operazioni questa volta utilizzeremo un metodo della libreria librosa che esegue in pipeline le operazioni effettuate in precedenza, quindi:

stft -> decompose.hpss -> istft

Otteniamo quindi le due parti già divise

Eseguo e plotto la parte armonica

Eseguo e plotto la parte percussiva

Risultati

In questo notebook abbiamo scomposto la traccia audio in parte armonica e percussiva tramite applicazione di maschere. I risultati intermedi sono ottimi ma durante la parte cantata si crea confusione su parte armonica e percussiva e viene riprodotta in entrambi, sebbene nella parte percussiva sia poco presente.

Dopo aver rimosso la parte vocale i risultati sono migliori da una parte, in quanto la voce viene rimossa quasi totalmente, ma peggiori dall'altra perché la maschera vocale ha sfasato la parte armonica della canzone.

Tuttavia, il risultato varia molto dalla canzone che scegliamo perché la scomposizione avviene tramite maschere applicate alla traccia e il margine è fondamentale per la riuscita. Per ogni canzone bisogna trovare il margine ideale che riesca a isolare le singole parti, di seguito una parte extra per la dimostrazione.

Parte Extra, dimostrazione del margine ideale:

In questa parte mostriamo come per una canzone diversa dalla precedente il risultato con gli stessi parametri non sia soddisfacente.

Inizializziamo la seconda canzone

Rimuoviamo la voce utilizzando lo stesso procedimento

Riscriviamo l'algoritmo

Questa volta non creiamo delle maschere ma andiamo direttamente a ritornare i due spettrogrammi con lo stesso margine.

Adesso invece con i margini ideali per la canzone

Considerazioni finali

La scelta della seconda canzone non è casuale, infatti è stata presa una canzone che fosse complicata da scomporre, le frequenze vocali non si riescono a rimuovere molto facilmente poiché sono molto simili alle note dell'organo in sottofondo e le singole parti quindi vengono influenzate dalla costante presenza dell'organo e della voce.

Librosa è una libreria che ci permette di scrivere in poche righe un programma che ha molte funzionalità, tuttavia ha molti difetti perché la potenza di questo strumento è molto limitata